package com.ruoyi.project.comp.h5;

import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.security.ShiroUtils;
import com.ruoyi.framework.shiro.service.PasswordService;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.project.comp.work.domain.CompWork;
import com.ruoyi.project.comp.work.service.ICompWorkService;
import com.ruoyi.project.system.user.domain.User;
import com.ruoyi.project.system.user.service.IUserService;
import me.chanjar.weixin.common.bean.WxOAuth2UserInfo;
import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.service.WxOAuth2Service;
import me.chanjar.weixin.mp.api.WxMpService;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.*;

/**
 * 微信授权与用户身份相关控制层（完全适配WxMpService接口源码）
 */
@Controller
@RequestMapping("/h5/user")
public class WechatAuthController extends BaseController {

    @Value("${wechat.redirect-uri}")
    private String CALLBACK_URL;

    @Value("${wechat.token}")
    private String token;

    @Autowired
    private WxMpService wxMpService; // 微信SDK核心服务

    @Autowired
    private IUserService sysUserService; // 若依用户服务（操作sys_user表）

    // 微信授权范围常量（直接使用字符串，替代枚举）
    private static final String OAUTH_SCOPE_USER_INFO = "snsapi_userinfo";

    @Autowired
    private PasswordService passwordService;

    @Autowired
    private ICompWorkService compWorkService;
    /**
     * 1. 微信授权登录（引导用户跳转微信授权页面）
     * 核心：通过 wxMpService.getOAuth2Service() 获取 WxOAuth2Service 实例
     */
    @GetMapping("/wechat/auth")
    public void wechatAuth(HttpServletResponse response) throws IOException, WxErrorException {
        // 步骤1：获取 OAuth2 服务实例（从 WxMpService 中获取，与源码一致）
        WxOAuth2Service oauth2Service = wxMpService.getOAuth2Service();

        // 步骤2：构建授权URL（使用 WxOAuth2Service 的方法，传入回调地址、授权范围、state）
        String authUrl = oauth2Service.buildAuthorizationUrl(
                CALLBACK_URL,
                OAUTH_SCOPE_USER_INFO, // 授权范围：获取用户信息
                null // state参数（可选，防CSRF）
        );

        // 步骤3：重定向到微信授权页面
        response.sendRedirect(authUrl);
    }




        /**
         * 处理微信服务器配置验证（GET请求，带echostr参数）
         */
    @GetMapping("/wechat/validate")
    @ResponseBody
    public String validateServerConfig(
            @RequestParam("signature") String signature,
            @RequestParam("timestamp") String timestamp,
            @RequestParam("nonce") String nonce,
            @RequestParam("echostr") String echostr) {
        try {
            // 验证签名（确保请求来自微信服务器）
            List<String> params = Arrays.asList(token, timestamp, nonce);
            Collections.sort(params);
            String sign = DigestUtils.sha1Hex(String.join("", params));
            if (sign.equals(signature)) {
                // 签名验证通过，返回echostr（微信要求）
                return echostr;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 签名验证失败，返回空
        return "";
    }



    /**
     * 2. 微信授权回调（用户授权后微信回调此接口）
     */
    @RequestMapping("/wechat/callback")
    public String wechatCallback(
            @RequestParam(value = "code", required = false) String code,
            HttpServletRequest request, ModelMap mmap) {
        request.getParameterMap().forEach((key, values) -> {
            System.out.println(key + "=" + String.join(",", values));
        });

        try {
            if(StringUtils.isEmpty(code)){
                code = request.getParameter("code");
            }

            // 步骤1：获取 OAuth2 服务实例
            WxOAuth2Service oauth2Service = wxMpService.getOAuth2Service();
            // 步骤2：通过code获取 access_token（使用 WxOAuth2Service 方法）
            WxOAuth2AccessToken accessToken = oauth2Service.getAccessToken(code);
            // 步骤3：通过 access_token 和 openid 获取用户信息
            WxOAuth2UserInfo wxUserInfo = oauth2Service.getUserInfo(accessToken, null);
            // 提取核心用户信息
            String openid = wxUserInfo.getOpenid(); // 微信唯一标识（必须存入sys_user表）
            String nickname = wxUserInfo.getNickname(); // 微信昵称（已处理编码）
            String avatar = wxUserInfo.getHeadImgUrl(); // 微信头像URL
            // 步骤4：检查用户是否已存在（按openid查询sys_user表）
            User queryUser = new User();
            queryUser.setRemark(openid);
            queryUser.setDelFlag("0");
            //User existUser = sysUserService.selectUserByOpenid(openid);
            List<User> userList = sysUserService.selectUserList(queryUser);
            User existUser = null;
            if (userList != null && userList.size() > 0) {
                existUser = userList.get(0);
            }
            User currentUser;

            if (existUser == null) {
                // 新用户自动创建（默认身份：普通客户）
                currentUser = new User();
                currentUser.setRemark(openid);// TODO openid
                currentUser.setUserName(nickname);
                currentUser.setLoginName(nickname);
                currentUser.setAvatar(avatar);
                currentUser.setUserType("02"); // 02=普通客户
                currentUser.setStatus("0"); // 状态：正常（0=正常，1=禁用）
                // 生成随机初始密码（若依框架自动BCrypt加密）
                currentUser.setPassword("12345678");
                sysUserService.insertUser(currentUser); // 若依标准新增接口
            } else {
                // 老用户更新昵称和头像
                existUser.setRemark(openid);
                existUser.setUserName(nickname);
                existUser.setAvatar(avatar);
                sysUserService.updateUser(existUser); // 若依标准更新接口
                currentUser = existUser;
            }

            // 步骤5：用户信息存入Session，用于后续操作
            request.getSession().setAttribute("loginUser", currentUser);

            // 步骤6：跳转回"我的"页面，携带用户信息
            mmap.put("user", currentUser);
            return "redirect:/h5/index_yonghu"; // 对应前端页面路径
            //return "redirect:/h5/index";
        } catch (Exception e) {
            e.printStackTrace();
            // 授权失败跳转首页
            //return "redirect:/h5/index";
            return "redirect:/h5/index_yonghu";
        }
    }

    /**
     * 3. 身份绑定（学生评委/教师评委）
     */
    @PostMapping("/bindJudge")
    @ResponseBody
    public AjaxResult bindJudge(
            @RequestParam("identityType") String identityType, // student=学生评委，teacher=教师评委
            @RequestParam("account") String account, // 评委账号（提前录入系统）
            @RequestParam("password") String password, // 评委密码
            HttpServletRequest request) {
        // 验证当前用户是否已登录
        User loginUser = (User) request.getSession().getAttribute("loginUser");
        if (loginUser == null) {
            return AjaxResult.error("请先微信授权登录");
        }
        String userType = "student".equals(identityType) ? "03" : "04";
        User queryUser = new User();
        queryUser.setUserType(userType);
        List<User> userList = sysUserService.selectUserList(queryUser);
        String currpassword = "";
        boolean authSuccess = false;

        User nouser = loginUser;

        for (int i = 0; i < userList.size(); i++) {
            User user = userList.get(i);
            currpassword = passwordService.encryptPassword(account, password, user.getSalt());
            if (user != null
                    && StringUtils.isNotEmpty(user.getUserType())
                    && StringUtils.isNotEmpty(user.getLoginName())
                    && StringUtils.isNotEmpty(user.getPassword())
                    && user.getLoginName().equals(account)
                    && user.getPassword().equals(currpassword)) {
                authSuccess = true;
                loginUser = user;
                break;
            }
        }
        if (!authSuccess) {
            return AjaxResult.error("评委账号或密码错误");
        }
        loginUser.setUserType(userType);
        loginUser.setRemark(nouser.getRemark());
        loginUser.setAvatar(nouser.getAvatar());
        sysUserService.updateUser(loginUser); // 若依标准更新接口


        sysUserService.deleteUserById(nouser.getUserId()); // 若依标准更新接口


        // 更新Session中的用户信息
        request.getSession().setAttribute("loginUser", loginUser);
        return AjaxResult.success("身份绑定成功", loginUser);
    }

    /**
     * 4. 获取当前登录用户信息（前端页面初始化时调用）
     */
    @GetMapping("/getLoginUser")
    @ResponseBody
    public AjaxResult getLoginUser(HttpServletRequest request) {
        User loginUser = (User) request.getSession().getAttribute("loginUser");
        return loginUser != null ? AjaxResult.success(loginUser) : AjaxResult.error("用户未登录");
    }

    /**
     * 5. 退出登录
     */
    @GetMapping("/logout")
    public String logout(HttpServletRequest request) {
        try {
            // 清除Session（若依框架可结合Shiro登出，此处简化处理）
            request.getSession().removeAttribute("loginUser");
            request.getSession().invalidate();
            return "redirect:../../h5/index"; // 退出后跳转首页
        }catch (Exception e){
            e.printStackTrace();
            return "redirect:../../h5/index"; // 退出后跳转首页
        }
    }


    /**
     * 获取当前用户的作品列表
     */
    @GetMapping("/getMyWorks")
    @ResponseBody
    public AjaxResult getMyWorks(HttpServletRequest request) {
        try {
            // 获取当前登录用户
            User loginUser = (User) request.getSession().getAttribute("loginUser");
            if (loginUser == null) {
                return AjaxResult.error("用户未登录");
            }

            // 查询当前用户的作品
            CompWork workQuery = new CompWork();
            workQuery.setParticipantUserId(loginUser.getUserId()); // 假设作品表中用create_by存储用户ID
            List<CompWork> workList = compWorkService.selectCompWorkList(workQuery);

            // 按创建时间倒序排列
            workList.sort((w1, w2) -> w2.getCreatedAt().compareTo(w1.getCreatedAt()));

            // 封装返回结果
            return AjaxResult.success(workList);
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("获取作品列表失败");
        }
    }







        /**
         * 获取分享数据
         */
        @GetMapping("/shareData")
        @ResponseBody
        public AjaxResult getShareData(@RequestParam(required = false) Long workId) {
            Map<String, String> shareData = new HashMap<>();

            if (workId != null) {
                // 作品分享
                CompWork work = compWorkService.selectCompWorkById(workId);
                if (work != null) {
                    shareData.put("title", work.getWorkName());
                    shareData.put("desc", StringUtils.substring(work.getWorkIntro(), 0, 50) + "...");
                    //shareData.put("imgUrl", work.getWorkCover());
                    shareData.put("imgUrl", "https://shuidicms.cn/templates/h5/assets/pictures/banner.jpg");
                }
            }

            // 默认数据
            if (shareData.isEmpty()) {
                shareData.put("title", "数智化赋能微情境微宣讲红色实践活动");
                shareData.put("desc", "数智点亮红色传承，创新砥砺时代英才");
                shareData.put("imgUrl", "https://shuidicms.cn/templates/h5/assets/pictures/banner.jpg");
            }

            shareData.put("link", getCurrentUrl(workId));
            return AjaxResult.success(shareData);
        }

        private String getCurrentUrl(Long workId) {
            // 返回当前网站域名 + H5路径
            return "https://shuidicms.cn/h5/index_zuopin?id="+workId;
        }


    @Value("${wechat.appid}")
    private String appId;

    @Value("${wechat.appsecret}")
    private String appSecret;

    /**
     * 获取微信配置
     */
    @GetMapping("/config")
    @ResponseBody
    public AjaxResult getConfig(@RequestParam String url) {
        try {
            // 1. 获取access_token
            String accessToken = getAccessToken();

            // 2. 获取jsapi_ticket
            String jsapiTicket = getJsapiTicket(accessToken);

            // 3. 生成签名
            Map<String, String> config = generateSignature(jsapiTicket, url);
            config.put("appId", appId);

            return AjaxResult.success(config);
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("获取配置失败");
        }
    }

    /**
     * 获取access_token
     */
    private String getAccessToken() throws Exception {
        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" +
                appId + "&secret=" + appSecret;

        // 使用HttpClient或RestTemplate调用微信接口
        String result = httpGet(url);
        JSONObject json = JSONObject.parseObject(result);

        if (json.containsKey("access_token")) {
            return json.getString("access_token");
        } else {
            throw new Exception("获取access_token失败: " + json);
        }
    }

    /**
     * 获取jsapi_ticket
     */
    private String getJsapiTicket(String accessToken) throws Exception {
        String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" +
                accessToken + "&type=jsapi";

        String result = httpGet(url);
        JSONObject json = JSONObject.parseObject(result);

        if (json.getIntValue("errcode") == 0) {
            return json.getString("ticket");
        } else {
            throw new Exception("获取jsapi_ticket失败: " + json);
        }
    }

    /**
     * 生成签名
     */
    private Map<String, String> generateSignature(String jsapiTicket, String url) {
        String nonceStr = generateRandomStr();
        String timestamp = String.valueOf(System.currentTimeMillis() / 1000);

        // 1. 拼接字符串
        String string1 = "jsapi_ticket=" + jsapiTicket +
                "&noncestr=" + nonceStr +
                "&timestamp=" + timestamp +
                "&url=" + url;

        // 2. SHA1加密
        String signature = sha1(string1);

        Map<String, String> config = new HashMap<>();
        config.put("timestamp", timestamp);
        config.put("nonceStr", nonceStr);
        config.put("signature", signature);

        return config;
    }

    /**
     * 生成随机字符串
     */
    private String generateRandomStr() {
        return UUID.randomUUID().toString().replace("-", "").substring(0, 16);
    }

    /**
     * SHA1加密
     */
    private String sha1(String str) {
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-1");
            byte[] digest = md.digest(str.getBytes(StandardCharsets.UTF_8));
            return bytesToHex(digest);
        } catch (Exception e) {
            throw new RuntimeException("SHA1加密失败", e);
        }
    }

    /**
     * 字节数组转十六进制
     */
    private String bytesToHex(byte[] bytes) {
        StringBuilder hex = new StringBuilder();
        for (byte b : bytes) {
            hex.append(String.format("%02x", b));
        }
        return hex.toString();
    }

    /**
     * HTTP GET请求
     */
    private String httpGet(String url) throws IOException {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet(url);

        try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
            HttpEntity entity = response.getEntity();
            return EntityUtils.toString(entity, StandardCharsets.UTF_8);
        } finally {
            httpClient.close();
        }
    }
}